package cn.concurrent.notify;

/**
 * @Author: lz
 * @Date: 2018/8/31 17:22
 * @Version 1.0
 */
public class Order {

	// wait-notify 线程必须要获得该对象的对象监视器锁，即只能在同步方法或同步块
	private static String lockObject = "";

	// 为了防止通知以后，不在等待，在等待之外加white在使用线程的等待/通知机制时，
	// 一般都要配合一个 boolean 变量值（或者其他能够判断真假的条件），在 notify
	// 之前改变该 boolean 变量的值，让 wait 返回后能够退出 while 循环（一般都
	// 要在 wait 方法外围加一层 while 循环，以防止早期通知），或在通知被遗漏后，
	// 不会被阻塞在 wait 方法处。这样便保证了程序的正确性。
	private static boolean isWait = true;

	public static void main(String[] args) {
		WaitThread waitThread = new WaitThread(lockObject);
		NotifyThread notifyThread = new NotifyThread(lockObject);
		/// 1.正常情况 waitThread线程在 notifyThrea线程之前
/*		waitThread.start();

		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		notifyThread.start();
*/

		/// .非正常情况 notifyThrea在waitThread之前
		notifyThread.start();


		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		waitThread.start();
	}

	/**
	 * 等待线程
	 */
	static class WaitThread extends Thread {
		private String lock;

		public WaitThread(String lock) {
			this.lock = lock;
		}

		@Override
		public void run() {
			synchronized (lock) {
				while (isWait) {
					try {
						System.out.println(Thread.currentThread().getName() + "  进去代码块wait");
						System.out.println(Thread.currentThread().getName() + "  开始wait");
						lock.wait();
						System.out.println(Thread.currentThread().getName() + "   结束wait");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	/**
	 * 唤醒线程
	 */
	static class NotifyThread extends Thread {
		private String lock;

		public NotifyThread(String lock) {
			this.lock = lock;
		}

		@Override
		public void run() {
			synchronized (lock) {
				System.out.println(Thread.currentThread().getName() + "  进去代码块notify");
				System.out.println(Thread.currentThread().getName() + "  开始notify");
				lock.notify();
				isWait = false;
				System.out.println(Thread.currentThread().getName() + "   结束开始notify");
			}
		}
	}

}
